<script setup lang="ts">
import { nextTick, ref, watch } from 'vue'
import { copyText } from '@/utils/copyTextToClipboard'
import HistoryLog from './asstInfo/compent/historyLog.vue'
import { ElDialog, vLoading } from 'element-plus'
import { useRouter } from 'vue-router'
import {
  FullScreen,
  DocumentCopy,
  Link,
  Search,
  Promotion,
  Location,
  Aim,
  Clock,
  Monitor,
  Document
} from '@element-plus/icons-vue'

import hljs from 'highlight.js'
import Vditor from 'vditor';
import 'vditor/dist/index.css';
import 'highlight.js/styles/github-dark.css';

const router = useRouter()
const props = defineProps({
  info: {
    type: Object,
    required: true,
    default: () => { }
  }
})
const infoId = props.info.id
// 历史变更显示状态
const HisVisible = ref(false)
// 全屏Banner显示状态
const BanVisible = ref(false)
const BanContent = ref()
// Vditor盒子
const VRef = ref()
// Vditor实例
const vditorInstance = ref();
// loading状态
const loadFlag = ref(false)
// GPT抽屉状态
const XGPVisible = ref()
// GPT左侧Banner
const XGPContent = ref()
// GPT输出字符
const outStr = ref('')

// 搜索？
const search = (id: string) => {
  router.push({
    name: 'SearchDomain',
    params: {
      id: id
    }
  })
}
// 链接跳转
const link = (url: any, service: any) => {
  if (['http', 'https'].includes(service)) {
    window.open(`${service}://${url}`, '_blank')
  }
  return
}
// 手动分析
const analy = (ip: string) => {
  router.push({
    name: 'AnalysisManual',
    params: {
      ip: ip
    }
  })
}
// 查看历史变更记录
const open = () => {
  HisVisible.value = true
}
// 全屏Banner
const openDialog = (Banner: any) => {
  BanVisible.value = true
  BanContent.value = Banner
}
// 跳转到详情页
const linkInfo = (id: string) => {
  router.push({
    name: 'SearchAssetInfo',
    params: {
      id: id
    }
  })
}
// 跳转到域名详情
const linkHost = (id: string) => {
  router.push({
    name: 'SearchDomain',
    params: {
      id: id
    }
  })
}

// XGPT解读
const XGPT = (value: any, service: any, protocol: any, port: any) => {
  XGPContent.value = modifyString(value)
  XGPVisible.value = true
  outStr.value = ''
  loadFlag.value = true

  fetch('cy/asset/xgpt', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({ banner: modifyString(value, true), service, protocol, port }) // 只传递一次参数
  })
    .then(async (response: any) => {
      const reader = response.body.getReader() // 读取流
      const decoder = new TextDecoder() // 处理流文本
      loadFlag.value = false
      while (true) {
        const { done, value } = await reader.read()
        if (done) {
          console.log("传输完成!!!");
          break
        }

        let text = decoder.decode(value, { stream: true }).replace(/data:/g, '').replace(/(\[DONE\])?/g, '').trim();
        const contentMatch = text.match(/"content":"([^"]+)"/);//返回数据是字符串
        if (contentMatch && contentMatch[1]) {
          const contentValue = contentMatch[1].replace(/\\n/g, '\n').replace(/\\"/g, '"'); // 处理转义字符
          outStr.value += contentValue
          if (vditorInstance.value) {
            vditorInstance.value.setValue(outStr.value);
          }
        }

      }
    })
    .catch((error) => {
      console.error('连接错误:', error)
      loadFlag.value = false
    })
}

// Banner正则
const modifyString = (text: string, XGPtFlag?: boolean) => {
  const newStr = text
    .replace(/^["<br> \n\r]+|["\n\r]+$/g, '')
    .replace(/^\\n/g, '')
    .replace(/(?:\\r\\n|\\r|\\n)+/g, '<br>')
    .replace(/\\"|\\/g, '')
    .replace(/: <br> /g, ':')
  if (XGPtFlag) {
    return newStr.replace(/<br>/g, ' ')
  }
  return newStr
}

// 获取base64图片前缀
const getBase64Url = (base64Data: string) => {
  return `data:image/png;base64,${base64Data}`
}

const VitorInit = () => {
  nextTick(() => {
    if (VRef.value) {
      vditorInstance.value = new Vditor(VRef.value, {
        height: 500,
        value: outStr.value,
        cache: {
          enable: false,
          id: 'VditorValue',
        },
        preview: {
          hljs: {
            enable: true,
            style: "github-dark",
            lineNumber: true,
          }
        },
        toolbar: [],
        after: () => {
          console.log('Vditor is ready');
        },
      });
    }
  });
}
watch(XGPVisible, (newVal) => {
  if (newVal) {
    // 弹窗显示时初始化 Vditor
    nextTick(() => {
      VitorInit();
    });
  } else {
    // 弹窗关闭时销毁 Vditor
    if (vditorInstance.value) {
      vditorInstance.value.destroy();
      vditorInstance.value = null;
    }
  }
});
</script>
<template>
  <div class="listbox" @click="HisVisible || BanVisible || XGPVisible ? null : linkInfo(props.info.id)">
    <div class="nav flex">
      <div class="nav-l flex">
        <div class="icon flex" v-if="props.info?.html?.favicon">
          <img :src="getBase64Url(props.info?.html?.favicon)" style="width: 1.25rem" />
        </div>
        <div class="title">{{ props.info.id }}</div>
        <div class="tag">{{ props.info.port }}</div>
        <div class="tag">{{ props.info.protocol }}</div>
      </div>
      <div class="nav-r flex">
        <jm-button :icon="Document" @click.stop="open">查看历史变更记录</jm-button>
      </div>
    </div>
    <div class="main flex">
      <div class="menu">
        <div class="desc">
          <jm-icon class="icon">
            <Location />
          </jm-icon>
          <span class="desc-title">位置: </span>
          <span>{{ props.info.location }}</span>
        </div>
        <div class="desc">
          <jm-icon class="icon">
            <Aim />
          </jm-icon>
          <span class="desc-title">类型: </span>
          <span>{{ props.info.deviceInformation.secondaryType }}</span>
        </div>
        <div class="desc">
          <jm-icon class="icon">
            <Clock />
          </jm-icon>
          <span class="desc-title">更新时间: </span>
          <span>{{ props.info.updateTime }}</span>
        </div>
        <div class="desc">
          <jm-icon class="icon">
            <Monitor />
          </jm-icon>
          <span class="desc-title">操作系统: </span>
          <span>{{ props.info.os }}</span>
        </div>
      </div>
      <div class="textbox">
        <div class="textnav flex">
          <div class="flex-align">
            <div class="title">Banner</div>
            <!-- 复制 -->
            <jm-icon @click.stop="copyText(props.info.id)" class="clickbtn">
              <DocumentCopy />
            </jm-icon>
            <!-- 链接跳转 -->
            <jm-icon @click.stop="link(props.info.id, props.info.service)" class="clickbtn">
              <Link />
            </jm-icon>
            <!-- 搜索 -->
            <jm-icon @click.stop="search(props.info.id)" class="clickbtn">
              <Search />
            </jm-icon>
            <!-- 手动分析 -->
            <jm-icon @click.stop="analy(props.info.ip)" class="clickbtn">
              <Promotion />
            </jm-icon>
          </div>
          <div class="flex-align">
            <div class="XGPTbtn"
              @click.stop="XGPT(props.info.banner, props.info.service, props.info.protocol, props.info.port)">
              GPT解读
            </div>
            <!-- 全屏查看 -->
            <jm-icon class="fullIcon" @click="openDialog(props.info.banner)">
              <FullScreen />
            </jm-icon>
          </div>
        </div>
        <hr class="line" />
        <div class="scrollbox">
          <div v-html="modifyString(props.info.banner)"></div>
        </div>
      </div>
    </div>
    <div>
      <!-- 历史变更显示 -->
      <jm-dialog v-model="HisVisible" title="Tips" width="900">
        <template #header>
          <div class="header flex-items">
            <div class="title">历史变更</div>
            <div class="desc">6个月历史资产测绘数据变更</div>
          </div>
          <HistoryLog v-model:id="infoId" />
        </template>
        <HistoryLog v-model:id="infoId" />
      </jm-dialog>
      <!-- Banner全部显示 -->
      <jm-dialog v-model="BanVisible" :modal="true">
        <template #header>
          <p v-html="modifyString(BanContent)"></p>
        </template>
      </jm-dialog>
      <!-- XGPT解读 -->
      <el-dialog v-model="XGPVisible" :modal="true" title="IPBanner 解读">
        <div class="GPTBox flex">
          <!-- 左侧内容显示 -->
          <div class="GPTL" v-html="XGPContent">
          </div>
          <!-- 右侧解读 -->
          <div class="GBTR">
            <!-- loading -->
            <div class="XGPTLoading" v-loading="loadFlag" v-if="loadFlag"></div>
            <!-- 加载内容 -->
            <div class="XGPTText" ref="VRef" v-show="!loadFlag"></div>
          </div>
        </div>
      </el-dialog>
    </div>
  </div>
</template>

<style scoped lang="scss">
.GPTBox {
  width: 100%;
  height: 500px;

  .GPTL {
    width: 40%;
    padding: 1rem;
    line-height: 20px;
  }

  .GBTR {
    width: 60%;
    scrollbar-gutter: stable;

    .XGPTLoading {
      height: 100%;
      justify-content: center;
      align-items: center;
    }

    .XGPTText {
      // border: 1px solid;
      white-space: pre-wrap;
      background-color: #f5f6f8;
      overflow: auto;

      :deep(strong) {
        font-weight: 600;
      }
    }


  }

}


.flex-align {
  display: flex;
  align-items: center;

  .XGPTbtn {
    color: #666;
    background-color: #eef3fc;
    margin-right: 0.5rem;
    border: 1px solid #eef3fc;
    border-radius: 0.3rem;
    font-size: 14px;
    line-height: 14px;
    cursor: pointer;

    &:hover {
      color: #0d7cf2;
    }
  }
}

.listbox {
  width: 100%;
  margin-bottom: 0.5rem;
  border: 0.0625rem solid #eee;
  overflow: hidden;

  &:hover {
    box-shadow: 0.125rem 0.125rem 0.3125rem 0.1875rem rgba(123, 122, 122, 0.3);
  }

  .nav {
    height: 2.8125rem;
    padding: 0 0.5rem;
    background-color: #e0eafc;
    justify-content: space-between;
    align-items: center;
    border-bottom: 0.0625rem solid #eee;

    .nav-l {
      align-items: center;

      .icon {
        margin-right: 0.3rem;
        align-items: center;
      }

      .title {
        font-size: 1.4rem;
        font-weight: 700;
        color: #6e6e6e;
        cursor: pointer;

        &:hover {
          color: var(--el-color-primary);
        }
      }

      .tag {
        align-items: center;
        cursor: default;
        font-size: 1.25rem;
        margin-left: 0.5rem;
        padding: 0 0.5rem;
        color: #fff;
        background-color: #63b0ff;
        font-weight: 700;
        border-radius: 0.3rem;
      }
    }

    .nav-r {}
  }

  .main {
    width: 100%;

    .menu {
      width: 30%;
      margin-left: 0.3125rem;
      border-right: 0.0625rem solid #eee;

      .desc {
        display: flex;
        align-items: center;
        margin: 1rem 0;

        .icon {
          font-size: 1.425rem;
          color: var(--el-color-primary);
          font-weight: 700;
          margin-right: 0.3125rem;
        }

        .desc-title {
          font-size: 0.925rem;
          font-weight: 700;
          margin-right: 0.625rem;
          color: rgb(77, 80, 86);
        }
      }
    }

    .textbox {
      flex: 1;
      overflow: hidden;

      .textnav {
        height: 1.5625rem;
        align-items: center;
        justify-content: space-between;

        .title {
          color: #0d7cf2;
          font-weight: 500;
          padding: 0 0.5rem;
        }

        .clickbtn {
          cursor: pointer;
          margin-left: 0.2rem;

          &:hover {
            color: var(--el-color-primary);
          }
        }

        .fullIcon {
          margin-right: 0.5rem;
          cursor: pointer;

          &:hover {
            color: var(--el-color-primary);
          }
        }
      }

      .line {
        border: 0.0625rem solid #eee;
        margin: 0;
      }

      .scrollbox {
        max-width: 55rem;
        overflow: auto;
        height: 9.6875rem;
        padding: 0 0.5rem;
        color: #747d8c;

        &::-webkit-scrollbar-track-piece {
          background-color: var(--el-fill-color-blank);
        }

        &::-webkit-scrollbar {
          width: 0.375rem;
          height: 0.375rem;
        }

        &::-webkit-scrollbar-thumb {
          border-radius: 1.25rem;
          background-color: var(--el-text-color-disabled);

          &:hover {
            background-color: #888;
          }
        }
      }
    }
  }
}
</style>
